<template>
  <div class="permission-container">
    <!-- 员工列表，仅限选择卡片式时展示 -->
    <div
      :class="{
        'block employee-list': true,
        isFold: mode === 'table'
      }"
    >
      <header>
        <div class="search">
          <el-input v-model="employee_filter" size="mini" placeholder="筛选员工">
            <i slot="prefix" class="iconfont icon-search"></i>
          </el-input>
        </div>
        <div class="search-results" :style="{ height: isFiltering ? '100%' : '0' }">
          <div v-if="employee_search_result.length === 0" class="empty">
            <empty><span>未查询到用户</span></empty>
          </div>
          <div v-else class="results-list">
            <div
              v-for="employee in employee_search_result"
              :key="employee.Name"
              class="row"
              @click="
                onSelectedChange({ name: employee.Name, department: employee.DepartmentName })
              "
            >
              {{ employee.Name }} / {{ employee.Position }} / {{ employee.DepartmentName }}
            </div>
          </div>
        </div>
      </header>
      <section>
        <ws-apartment-group
          :list="employee_total_list"
          :activeEmployee="selected_employee"
          :accordion="true"
          @select-employee="onSelectedChange"
        />
      </section>
      <footer>
        <el-button type="primary" size="mini">创建角色</el-button>
        <el-button type="danger" size="mini">删除角色</el-button>
      </footer>
    </div>
    <!-- 权限编辑模块 -->
    <div ref="panel" class="block power-division">
      <header :class="`header_${size}`">
        <div class="header-title">
          <h4>
            权限编辑<span v-if="mode === 'fold'">{{ '【' + selected_employee.name + '】' }}</span>
          </h4>
          <div class="button-container">
            <el-button type="primary" size="mini" :circle="size !== 'primary'">
              <i class="iconfont icon-upload" />
              <span class="text">保存</span>
            </el-button>
            <template v-if="mode === 'fold'">
              <el-button
                type="primary"
                size="mini"
                :circle="size !== 'primary'"
                @click="foldAllCollpase"
              >
                <i class="iconfont icon-folder" />
                <span class="text">{{ activeNames.length === 0 ? '全部展开' : '全部折叠' }}</span>
              </el-button>
            </template>
            <template v-if="mode === 'table'">
              <div class="search">
                <el-input v-model="employee_filter" size="mini" placeholder="筛选员工">
                  <i slot="prefix" class="iconfont icon-search"></i>
                </el-input>
              </div>
            </template>
          </div>
        </div>
        <div
          :class="{
            'mode-change': true,
            importer: mode === 'fold'
          }"
          @click="changeMode"
        />
      </header>
      <section v-if="mode === 'fold'">
        <el-collapse v-model="activeNames">
          <el-collapse-item
            v-for="(value, name) in Permission_zh"
            :key="name"
            :title="value.label"
            :name="name"
          >
            <template slot="title">
              <span>{{ value.label }}</span>
              <permission-change
                :min="0"
                :max="2"
                :name="name"
                :BeforeEdit="beforeEdit"
                @onNumChange="onPermissionChange"
              />
            </template>
            <ul class="collapse-content_list">
              <li v-for="(sub_value, sub_key) in value.limits" :key="sub_key">
                <span class="operation-title">{{ sub_value }}</span>
                <div class="operation-box" @click="onPermissionClick($event, sub_key)">
                  <span
                    v-for="n in 3"
                    :key="n"
                    :class="{
                      active: Permission_value[sub_key] === String(n - 1)
                    }"
                  >
                    {{ n - 1 }}
                  </span>
                </div>
              </li>
            </ul>
          </el-collapse-item>
        </el-collapse>
      </section>
      <section v-else>
        <el-table ref="table" size="mini" height="100%">
          <el-table-column prop="id" label="ID" fixed></el-table-column>
          <el-table-column prop="code" label="识别码" fixed></el-table-column>
          <el-table-column prop="name" label="姓名" fixed></el-table-column>
          <el-table-column
            v-for="(fir_column_value, fir_column_key) in Permission_zh"
            :key="fir_column_key"
            :label="fir_column_value.label"
          >
            <el-table-column
              v-for="(value, name) in fir_column_value.limits"
              :key="name"
              :prop="name"
              :label="value"
            ></el-table-column>
          </el-table-column>
        </el-table>
      </section>
    </div>
  </div>
</template>

<script lang="ts">
import Vue, { ComponentInstance } from 'vue'
import { Component, Watch, Ref } from 'vue-property-decorator'
import { GetEmployeeByDepartment } from '@/api/employee'
import { EmployeeType } from '@/store/interface/employee'
import { Permission_zh, PermissionType } from './settings/permission'
import empty from '@/components/basic/empty.vue'
import PermissionChange from './components/PermissionChange.vue'
import WsApartmentGroup from '@/components/tool/ws-apartment-group.vue'
import { Dictionary, ApartmentListType, BasicEmployeeType } from '@/interface/Basic'
import { AxiosResponse } from 'axios'
import { Getter } from 'vuex-class'
@Component({
  components: {
    empty,
    PermissionChange,
    WsApartmentGroup
  }
})
class PermissionManage extends Vue {
  @Getter('name') name!: string
  @Ref() panel!: HTMLElement
  @Ref() table!: ComponentInstance
  // left part - search component relative
  employee_filter: string = ''
  isFiltering: boolean = false
  employee_search_result: EmployeeType[] = []
  // employees list component relative
  employee_total_list: ApartmentListType = []
  selected_employee: {
    name: string
    department: string
  } = {
    name: '',
    department: ''
  }
  // right part - header component relative
  mode: 'table' | 'fold' = 'fold'
  size: 'mini' | 'medium' | 'primary' = 'primary'
  // permission component relative
  Permission_zh = Permission_zh
  Permission_value: Dictionary<string> = {}
  activeNames: string[] = []
  @Watch('employee_filter')
  ef_handler(newVal: string) {
    this.isFiltering = newVal.length !== 0
    if (newVal === '') {
      this.employee_search_result = []
      return
    }
    this.employee_search_result = this.employee_total_list
      .map(li => {
        return li.employees.map(employee => {
          return {
            Name: employee.name.toString(),
            Position: employee.position.toString(),
            DepartmentName: li.title
          }
        })
      })
      .flat()
      .filter(item => item.Name.indexOf(newVal) !== -1)
  }
  @Watch('Permission_zh', { immediate: true })
  pz_handler(newVal: Dictionary<PermissionType>) {
    this.activeNames = Object.keys(newVal)
  }
  mounted() {
    this.getEmployeesList()
    this.getLimits()
    this.initMode()
    this.computePanelSize()
    window.addEventListener('resize', () => {
      this.computePanelSize()
    })
  }
  // template
  computedLevel(position: string) {
    if (position.indexOf('经理') !== -1) return 2
    else if (position.indexOf('组长') !== -1) return 3
    else return null
  }
  // employee-list
  getEmployeesList() {
    GetEmployeeByDepartment({
      Departmentid: ['综合管理部', '装配车间', '职能组', '电子车间', '质量部']
    })
      .then((res: AxiosResponse<{ ReturnData: BasicEmployeeType[] }>) => {
        const { ReturnData } = res.data
        const map = new Map()
        const result: ApartmentListType = []
        ReturnData.forEach(employee => {
          const { Name, Position, DepartmentName } = employee
          if (Name === this.name && this.selected_employee.name === '') {
            this.selected_employee = {
              name: Name,
              department: DepartmentName
            }
          }
          const formated_employee = {
            name: Name,
            position: Position,
            level: this.computedLevel(Position)
          }
          if (!map.get(DepartmentName)) {
            map.set(DepartmentName, [formated_employee])
          } else {
            map.set(DepartmentName, [...map.get(DepartmentName), formated_employee])
          }
        })
        map.forEach((value, key) => {
          result.push({
            title: key,
            employees: [...value]
          })
        })
        this.employee_total_list = result
      })
      .catch(err => {
        console.log(err)
      })
  }
  onSelectedChange(employee: { name: string; department: string }) {
    this.selected_employee = employee
    this.employee_filter = ''
  }
  // panel_header
  computePanelSize() {
    const { width } = this.panel.getBoundingClientRect()
    if (width > 600) {
      // mode round
      this.size = 'primary'
    } else if (width > 500 && width < 600) {
      // mode circle
      this.size = 'medium'
    } else {
      this.size = 'mini'
    }
  }
  foldAllCollpase() {
    if (this.activeNames.length !== 0) this.activeNames = []
    else this.activeNames = Object.keys(this.Permission_zh)
  }
  initMode() {
    const result = localStorage.getItem('pcls-permission-prefer-mode')
    if (!result) {
      this.mode = 'fold'
      localStorage.setItem('pcls-permission-prefer-mode', 'card')
    } else this.mode = result as 'fold' | 'table'
  }
  changeMode() {
    this.mode = this.mode === 'fold' ? 'table' : 'fold'
    localStorage.setItem('pcls-permission-prefer-mode', this.mode)
  }
  getLimits() {
    // this.activeNames = []
    // 获取权限列表
    const permission_list = this.Permission_zh
    this.Permission_value = Object.keys(permission_list).reduce((accu, next) => {
      const { limits } = permission_list[next]
      const obj: Dictionary<string> = {}
      Object.keys(limits).forEach(key => {
        obj[key] = '0'
      })
      return { ...accu, ...obj }
    }, {})
  }
  beforeEdit(key: string) {
    return new Promise(resolve => {
      this.$confirm('此操作会将该模块下所有权限修改为相同值，确定继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
        center: true
      })
        .then(() => {
          this.bulkEditing(key, '0')
          resolve(true)
        })
        .catch(() => {
          this.$message({
            type: 'info',
            message: '已放弃操作'
          })
        })
    })
  }
  bulkEditing(key: string, value: string) {
    // 如果该模块操作前被折叠，则自动打开
    if (!this.activeNames.includes(key)) {
      this.activeNames.push(key)
    }
    // 将该模块下所有权限更新为相同值
    const { limits } = this.Permission_zh[key]
    Object.keys(limits).forEach(item => {
      this.Permission_value[item] = value
    })
  }
  onPermissionChange(obj: { key: string; num: string }) {
    const { key, num } = obj
    this.bulkEditing(key, num)
  }
  // collpase content
  onPermissionClick(e: MouseEvent, key: string | number) {
    const dom = e.target as HTMLElement
    this.Permission_value[String(key)] = dom.innerText
  }
}
export default PermissionManage
</script>

<style lang="less" scoped>
@import '~@/styles/theme.less';
@import '~@/styles/layout.less';
.permission-container {
  box-sizing: border-box;
  padding: 10px 20px;
  height: calc(100vh - 50px);
  #flex-start(row, space-between);
  #color(background-color, --primary-bg-color);
  .block {
    position: relative;
    box-sizing: border-box;
    padding: 10px;
    height: 100%;
    border-radius: 5px;
    overflow: hidden;
    #flex-center(column, space-between);
    #color(background-color, --module-bg-color);
    #shadow-color(0, 0, 4px, 0, --primary-shadow-color);
    header {
      width: 100%;
      margin-bottom: 20px;
      #flex-center(column, flex-start);
      .search-results {
        position: absolute;
        top: 40px;
        width: 100%;
        height: 0;
        z-index: 99;
        overflow: hidden;
        transition: all 0.5s ease;
        #color(background-color, --module-bg-color);
        .empty {
          height: 100%;
          width: 100%;
          #flex(row, center, center);
          span {
            font-size: 14px;
            #color(color, --primary-text-color);
          }
        }
      }
    }
    section {
      box-sizing: border-box;
      flex: 1;
      width: 100%;
      min-width: 200px;
      overflow: auto;
      #flex-center(column, flex-start);
    }
    footer {
      width: 100%;
      #flex-center(row, space-around);
    }
  }
  .employee-list {
    width: 300px;
    margin-right: 20px;
    overflow: hidden;
    transition: all 0.5s ease;
    header {
      .search {
        width: 100%;
        border-radius: 5px;
        #shadow-color(0, 0, 4px, 0, --primary-shadow-color);
      }
      .search-results {
        .row {
          box-sizing: border-box;
          padding: 10px;
          border-bottom: solid 1px;
          font-size: 14px;
          text-align: left;
          transition: all 0.2s ease;
          cursor: pointer;
          #color(color, --primary-text-color);
          #color(border-bottom-color, --primary-border-color);
        }
        .row:hover {
          #color(background-color, --gray-module-bg-color);
        }
      }
    }
  }
  .isFold {
    width: 0;
    margin: 0;
    padding: 0;
  }
  .power-division {
    flex: 1;
    box-sizing: border-box;
    padding: 20px;
    transition: all 0.5s ease;
    header {
      box-sizing: border-box;
      #flex(row, center, space-between);
      .header-title {
        flex-wrap: wrap;
        #flex(row, center, flex-start);
        h4 {
          margin: 0;
          margin-right: 20px;
          font-size: 20px;
          font-weight: 900;
          white-space: nowrap;
          #color(color, --primary-text-color);
        }
        .el-button {
          padding: 5px 10px;
          span {
            display: flex;
            align-items: center;
            justify-content: center;
            i {
              margin-right: 2px;
            }
          }
        }
        .is-circle {
          padding: 5px;
          span {
            display: none;
            i {
              margin-right: 0;
            }
          }
        }
        .button-container {
          margin: 8px 0;
          display: flex;
          align-items: center;
          justify-content: flex-start;
          .search {
            margin: 0 8px;
          }
        }
      }
      .mode-change {
        box-sizing: border-box;
        position: relative;
        padding: 6px;
        height: 30px;
        width: 100px;
        border-radius: 5px;
        box-shadow: inset 0 0 4px #929292;
        transition: all 0.2s ease;
        cursor: pointer;
        #color(background-color, --lighter-text-color);
      }
      .mode-change::before {
        content: '表格式';
        position: absolute;
        top: 12%;
        bottom: 12%;
        left: 5%;
        display: block;
        width: 50px;
        border-radius: 4px;
        font-size: 12px;
        transition: all 0.2s ease;
        #flex-center(row, center);
        #color(color, --primary-text-color);
        #color(background-color, --module-bg-color);
      }
      .importer::before {
        content: '折叠式';
        left: 100%;
        transform: translateX(-112%);
      }
    }
    .header_mini {
      align-items: flex-start;
      flex-direction: column;
    }
    .header_primary {
      /deep/.el-button {
        span {
          display: flex;
        }
      }
    }
    section {
      width: 100%;
      overflow: auto;
      .collapse-content_list {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        justify-content: flex-start;
        li {
          width: 220px;
          margin: 0 30px 10px 0;
          padding-right: 30px;
          display: flex;
          align-items: center;
          justify-content: space-between;
          border-right: solid 1px;
          #color(border-right-color, --primary-border-color);
          .operation-title {
            margin-right: 15px;
          }
          .operation-box {
            position: relative;
            box-sizing: border-box;
            span {
              display: inline-block;
              box-sizing: border-box;
              padding: 2px 8px;
              cursor: pointer;
              transition: all 0.2s ease;
              #color(background-color, --primary-bg-color);
            }
            span:hover {
              #color(background-color, --primary-hover-bg-color);
            }
            .active {
              color: #ffffff;
              #color(background-color, --primary-blue-color);
            }
          }
        }
        li:last-child {
          border-right: unset;
        }
      }
      /deep/.el-collapse {
        width: 100%;
        .el-collapse-item {
          .el-collapse-item__header {
            #flex(row, center, flex-start);
            span {
              margin-right: 3px;
            }
          }
          .el-collapse-item__content {
            padding-top: 10px;
          }
        }
      }
    }
  }
}
::-webkit-scrollbar {
  width: 0;
}
::-webkit-scrollbar-thumb {
  #color(background-color, --primary-border-color);
}
</style>
